classdef SupportVectorMachine < Classifier
    %SUPPORTVECTORMACHINE Summary of this class goes here
    %   Detailed explanation goes here
    
    properties ( SetAccess = protected )
        weightMode = 'default'; % {'default', 'auto', 'z_weight'}
        extraWeightScaleFactor = 1
        zWeight = []
    end
    
    methods
        function setWeightMode( this, weightMode )
            this.weightMode = weightMode;
        end
        
        function setExtraWeightScaleFactor( this, extraWeightScaleFactor )
            this.extraWeightScaleFactor = extraWeightScaleFactor;
        end
        
        function setZWeight( this, zWeight )
            this.zWeight = zWeight;
        end
    end
    
    methods
        function [ this ] = SupportVectorMachine( name )
            if nargin == 0
                this.setName('svm');
                return
            end
            if nargin >= 1
                this.setName(name);
            end
        end
    end
    
    methods ( Hidden = true )
        function [ optionString ] = genWeightOption( this, Y )
            switch this.weightMode
                case 'default'
                    optionString = '';
                case 'auto'
                    levels = unique(Y);
                    for iLevel = 1:length(levels)
                        z_weight(iLevel) = 1/nnz(Y == levels(iLevel));
                    end
                    z_weight = z_weight/(min(z_weight) + 1e-4);
                    z_weight(z_weight ~= 1) = z_weight(z_weight ~= 1)*this.extraWeightScaleFactor;
                    optionString = '';
                    for iLevel = 1:length(levels)
                        optionString = [optionString, ...
                            ' -w', num2str(levels(iLevel)), ' ', num2str(z_weight(iLevel))];
                    end
                case 'z_weight'
                        optionString = [' -w1 ', num2str(this.zWeight(1)), ...
                            ' -w2 ', num2str(this.zWeight(2))];
                otherwise
                    error('')
            end
        end
    end
    
end

